package cn.pkubangbang.demo.democontact.controller;

import cn.pkubangbang.demo.democontact.entity.CommonMessage;
import cn.pkubangbang.demo.democontact.entity.Person;
import cn.pkubangbang.demo.democontact.interceptor.TooFrequentRequestException;
import cn.pkubangbang.demo.democontact.service.AuthService;
import cn.pkubangbang.demo.democontact.service.PersonService;
import java.io.UnsupportedEncodingException;
import java.time.Instant;
import java.util.Base64;
import java.util.List;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @Author: zhangzhenbang@k2data.com.cn
 * @Date: 2018-08-24 11:12
 */
@Controller
@RequestMapping("/")
public class GeneralController {

    @Autowired
    private PersonService personService;

    @Value("${url.frontend.keystore}")
    private String frontEndKeyStoreUrl;

    @Autowired
    private AuthService authService;

    private static Logger logger = LoggerFactory.getLogger(GeneralController.class);

    /**
     * 在这个demo项目里，不另设置CAS，而是通过后台view的方式模拟一个“异地登录”的环境。
     * @return login 视图（后台渲染）
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String showLogin(Model model) {
        List<Person> people = personService.findPersonByName("");
        model.addAttribute("people", people);
        return "serverLogin";
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String handleLogin(@RequestParam("id") Integer userId)
        throws UnsupportedEncodingException {

        Person who = personService.getPersonById(userId);
        if (who != null) {
            // there he is.
            // note here JWT might be used as an implementation to the token generator, but
            // for simplicity, only a `username+time+random` will be created.
            String token = "";

            boolean done = false;
            for (int retry = 3; retry > 0; retry--) {

                token = authService.generateToken(who);
                try {
                    authService.touch(token);
                    done = true;
                    break;
                } catch (TooFrequentRequestException e) {
                    // should not be
                    logger.error(
                        "Throwing a TooFrequentRequestException when creating the token[{}], which is unnatual.",
                        token);
                    authService.invalid(token);
                }
            }
            if (done) {

                // simulate the process when TGT is confirmed and ST is ready to make.
                return "redirect:" + frontEndKeyStoreUrl + "?token=" + token;
            } else {

                // when login fail at confirming TGT phase, the main reason is
                // that TGT is not valid. In this case, user is sent to CAS.
                // todo is that right?
                return "redirect:/login";
            }

        } else {
            return "redirect:/login";
        }
    }

    @RequestMapping("/logout")
    public ResponseEntity<CommonMessage> handleLogout() {

        // todo 销毁session
        return null;
    }

    @RequestMapping("/menu")
    public ResponseEntity<CommonMessage> nextStep() {

        throw new UnsupportedOperationException("当前版本(v1.0)还没有实现这个功能，等着更新吧~");
        // 查询可用操作

    }

}
